home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / System / preferences-c.txt < prev    next >
Encoding:
Internet Message Format  |  1994-03-23  |  12.1 KB  |  [TEXT/EDIT]

  1. From: Sproul@sproul.sproul.com (Mark Sproul)
  2. Subject: Prefs file source code (C - long)
  3. Date: 2 Oct 92 09:05:30 GMT
  4.  
  5.  
  6. Several people asked for this source code.  As explained in the comments,
  7. it came from Inside Mac Comm Toolbox and there is a lot of code dealing
  8. just with the Comm Tool box setup.  It now handles the PREFERENCES
  9. folder in the system folder properly.
  10.  
  11. I have done some additions to the code to make it more general and
  12. usable as far as dealing with preferences.  Such as GET pref and SET
  13. pref.  This code was all written and runs correctly with Think C 5.0.
  14.  
  15. Its been several months since I wrote this and was looking at it.
  16. I may have forgotten to mention something, if you have any problems
  17. let me know and I will post updates.
  18.  
  19. You need to define some things such as this:
  20.  
  21. #define    creatorType        'abcd'
  22. #define    fileType        'PREF'
  23. #define    prefsFileName    "\pMyPreferences"
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30. /******************************************************************************
  31. * adapted from
  32. *  Inside the Macintosh Communications Toolbox
  33. * Page  333
  34. * After initialization, the code shown first checks if a
  35. * preferences folder, which contains tool settings written in preference
  36. * files, already exists. If so, the application uses the settings in this file.
  37. * Otherwise, the code generates a new preferences file.
  38. ******************************************************************************
  39. * Modifications
  40. ******************************************************************************
  41. * Nov 27, 1991    Original version had a bug in it.
  42. *                If the "Preferences" directory already existed, the preferences file
  43. *                was placed in the system folder, not in the "Preferences" directory.
  44. *                If the directory did NOT exist, everything worked fine.
  45. *                I also changed it to check for the existance of the "Preferences" folder
  46. *                first instead of trying to create one and letting an duplicate file error
  47. *                indicate that it already existed.
  48. *                by Mark Sproul
  49. *                Internet: sproul@sproul.com
  50. *                AppleLink: Sproul.M
  51. * Jan 16, 1992    Working on a general purpose prefs file manipulator
  52. * Jan 25, 1992    Prefs file resources working great
  53. ******************************************************************************/
  54.  
  55. #include    <Connections.h>
  56. #include    <CommResources.h>
  57.  
  58. /*
  59. ** Global Variables used by all of the prefs routines
  60. */
  61. long            prefDirID;            /* Prefs Dir ID number */
  62. long            sysfDirID;            /* System folder Dir ID number */
  63. short            prefVRefNum;        /* Prefs Volume Ref number */
  64. short            prefFileOKFlag = 0;    /* prefs file OK indicator */
  65.  
  66. /*************************************************************
  67. * This makes sure there is a prefs file in the PREFERENCES directory
  68. * if not, it creates it.
  69. *
  70. * getPrefsFile MUST be called before any atempt at getting the prefs values
  71. *
  72. *************************************************************/
  73.  
  74. void getPrefsFile(prefsFileName, creatorType, fileType)
  75. Str255        prefsFileName;
  76. OSType        creatorType;
  77. OSType        fileType;
  78. {
  79. OSErr            osErr        = noErr;
  80. SysEnvRec        theWorld;
  81. CInfoPBPtr        infoPB;
  82. WDPBPtr            wdPB;
  83. HParmBlkPtr        dirPB;
  84.  
  85. short            prefRefNum;
  86. Point            where    = { 75, 75 };
  87. Str63            toolName;
  88. short            procID;
  89. Handle            h;
  90. Ptr                p;
  91.  
  92.  
  93. ConnHandle        prefConn;
  94.  
  95. ConnHandle        docConn;
  96. CMBufferSizes    sizes    = { 0, 0, 0, 0, 0, 0, 0, 0 };
  97.  
  98.  
  99.  
  100.     infoPB        = (CInfoPBPtr)NewPtrClear(sizeof(*infoPB));
  101.     wdPB        = (WDPBPtr)NewPtrClear(sizeof(*wdPB));
  102.     dirPB        = (HParmBlkPtr)NewPtrClear(sizeof(*dirPB));
  103.  
  104.  
  105.     /* find the system folder's volume reference number and directory ID */
  106.     osErr = SysEnvirons(curSysEnvVers, &theWorld);
  107.     (*wdPB).ioVRefNum = theWorld.sysVRefNum;
  108.  
  109.     if (noErr == (osErr = PBGetWDInfo(wdPB, false)))
  110.     {
  111.         /*********************************************************
  112.         * 11-27-91 Modified by Mark Sproul
  113.         **********************************************************/
  114.         /* get the Volume Reference Number and save it */
  115.         prefVRefNum    = (*wdPB).ioWDVRefNum;
  116.         /* get the System directir ID and save it */
  117.         sysfDirID    = (*wdPB).ioWDDirID;
  118.         
  119.         /* check for the preferences folder */
  120.         (*infoPB).hFileInfo.ioFDirIndex    = 0;
  121.         (*infoPB).hFileInfo.ioVRefNum    = prefVRefNum;
  122.         (*infoPB).hFileInfo.ioDirID        = sysfDirID;
  123.         (*infoPB).hFileInfo.ioNamePtr    = "\pPreferences";
  124.         osErr = PBGetCatInfo(infoPB, false);
  125.         /* save the "Preferecnces" dir number */ 
  126.         prefDirID    = (*infoPB).hFileInfo.ioDirID;
  127.         
  128.         if (osErr == fnfErr)
  129.         {
  130.             /* Create "Preferences" folder */
  131.             (*dirPB).fileParam.ioVRefNum    = prefVRefNum;
  132.             (*dirPB).fileParam.ioDirID        = sysfDirID;
  133.             (*dirPB).fileParam.ioNamePtr    = "\pPreferences";
  134.             osErr = PBDirCreate(dirPB, false);
  135.             prefDirID    = (*dirPB).fileParam.ioDirID;
  136.         }
  137.  
  138.         /*********************************************************
  139.         * end of modifications
  140.         **********************************************************/
  141.         if (osErr == noErr)
  142.         {
  143.             /* does the preference file exist? */
  144.             (*infoPB).hFileInfo.ioFDirIndex    = 0;
  145.             (*infoPB).hFileInfo.ioVRefNum    = prefVRefNum;
  146.             (*infoPB).hFileInfo.ioDirID        = prefDirID;
  147.             (*infoPB).hFileInfo.ioNamePtr    = prefsFileName;
  148.             osErr = PBGetCatInfo(infoPB, false);
  149.             if (osErr == noErr)
  150.             {
  151.                 /* set flag saying the prefs file is OK */
  152.                 prefFileOKFlag = 0xAA;
  153.             }
  154.             if (osErr == fnfErr)
  155.             {
  156.                 /* no, so create a new preference file */
  157.                 if (noErr == (osErr = HCreate(prefVRefNum, prefDirID, prefsFileName, creatorType, fileType)))
  158.                 {
  159.                     HCreateResFile(prefVRefNum, prefDirID, prefsFileName);
  160.                     if (noErr == (osErr = ResError()))
  161.                     {
  162.                         /* open the preference file */
  163.                         prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsFileName, fsRdWrPerm);
  164.                         if (prefRefNum == -1)
  165.                         {
  166.                             osErr = ResError();
  167.                         }
  168.                         else
  169.                         {
  170.                             /* create a default connection */
  171.                             osErr = CRMGetIndToolName(classCM, 1,toolName);
  172.                             if (noErr == osErr)
  173.                             {
  174.                                 prefConn = CMNew(CMGetProcID(toolName), cmData, sizes, 0, 0);
  175.                                 /* leave the default setting as the preferance */
  176.                                 
  177.                                 /************************************************************
  178.                                 * ORIGINALLY, the code let the user select setup at this point
  179.                                 * I do not want it asking for serial port prefs on startup
  180.                                 * if they are not set.
  181.                                 * ---allow the user to select a prefered tool and configuration
  182.                                 * ---osErr = CMChoose(&prefConn, where, nil);
  183.                                 ************************************************************/
  184.                             
  185.                                 /* write the prefered tool name to the preference file */
  186.                                 HLock((Handle) prefConn);
  187.                                 CMGetToolName((**prefConn).procID, toolName);
  188.                                 HUnlock((Handle) prefConn);
  189.                                 h = NewHandle(1 + toolName[0]);
  190.                                 HLock(h);
  191.                                 BlockMove(toolName, *h, GetHandleSize(h));
  192.                                 HUnlock(h);
  193.                                 AddResource(h, 'pTXT', 0, "");
  194.                                 ReleaseResource(h);
  195.                                 /* write the prefered configuration to the preference file */
  196.                                 p = CMGetConfig(prefConn);
  197.                                 h = NewHandle(GetPtrSize(p));
  198.                                 HLock(h);
  199.                                 BlockMove(p, *h, GetHandleSize(h));
  200.                                 HUnlock(h);
  201.                                 AddResource(h, 'cTXT', 0, "");
  202.                                 ReleaseResource(h);
  203.                                 DisposPtr(p);
  204.                                 
  205.                                 /* dispose of the connection */
  206.                                 CMDispose(prefConn);
  207.                             }
  208.                             /* close the file so that it can be used in a shared environment */
  209.                             CloseResFile(prefRefNum);
  210.                             /* set flag saying the prefs file is OK */
  211.                             prefFileOKFlag = 0xAA;
  212.                         }
  213.                     }
  214.                 }
  215.             }
  216.         }
  217.     }
  218. }
  219.  
  220. //*****************************************************************
  221. //*
  222. //* The following code was written by Mark Sproul
  223. //* This code allows easy access to prefs file
  224. //*
  225. //*
  226. //*
  227. //*
  228. //*****************************************************************
  229.  
  230. /**************************************
  231. * get resource from Prefs file
  232. *
  233. ****************************************/
  234. getPrefsResourceStr(prefsFileName, perfsResType, returnString)
  235. Str255        prefsFileName;
  236. OSType        perfsResType;
  237. Str255        returnString;
  238. {
  239. short            prefRefNum;
  240. Handle            h;
  241. int                i;
  242. Size            hSize;
  243.  
  244.     h = nil;
  245.     /* did the prefs file get opened or created OK */
  246.     if (prefFileOKFlag == 0xAA)
  247.     {
  248.         /* focus on the preference file */
  249.         prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsFileName, fsRdWrPerm);
  250.         if (prefRefNum != -1)
  251.         {
  252.             h = Get1Resource(perfsResType, 0);
  253.             hSize = GetHandleSize(h);            /* get the size of the handle */
  254.             if (hSize > 255) hSize = 255;
  255.             HLock(h);
  256.             /* had to have this to make it compile under THINK C 5.0 */
  257.             for (i=0; i< hSize; i++)
  258.             {
  259.                 returnString[i] = *(*h+i);
  260.             }
  261.             HUnlock(h);
  262.             ReleaseResource(h);
  263.             CloseResFile(prefRefNum);
  264.         }
  265.     }
  266. }
  267.  
  268.  
  269. /**************************************
  270. * set Comm Tool Box connection preference
  271. *
  272. ****************************************/
  273. setCTBpref(prefsFileName)
  274. Str255        prefsFileName;
  275. {
  276. short            prefRefNum;
  277. OSErr            osErr, cmChooseReturnCode;
  278. int                i;
  279. Str255            prefStr;
  280. short            procID;
  281. Str63            toolName;
  282. Handle            h;
  283. Ptr                p;
  284. short            iErr;
  285. Size            hSize, newSize;
  286.  
  287. ConnHandle        docConn;
  288. CMBufferSizes    sizes    = { 0, 0, 0, 0, 0, 0, 0, 0 };
  289. Point            where    = { 75, 75 };
  290.  
  291.     if (isCTBavailable())
  292.     {
  293.         /* did the prefs file get opened or created OK */
  294.         if (prefFileOKFlag == 0xAA)
  295.         {
  296.             getPrefsResourceStr(prefsFileName,'pTXT', prefStr);
  297.     
  298.             procID = CMGetProcID(prefStr);
  299.             if (procID != -1)
  300.             {
  301.                 /* create a new connection */
  302.                 docConn    = CMNew(procID, cmData, sizes, 0, 0);
  303.                 
  304.                 if (docConn != nil)
  305.                 {
  306.                     /* set the prefered configuration */
  307.         
  308.                     getPrefsResourceStr(prefsFileName,'cTXT', prefStr);
  309.                     osErr    = CMSetConfig(docConn, (char *)prefStr);
  310.     
  311.                     cmChooseReturnCode    = CMChoose(&docConn, where, nil);
  312.                 }
  313.             }
  314.             else
  315.             {
  316.                 /* the prefered tool could not be found so I */
  317.                 osErr    = CRMGetIndToolName(classCM, 1, toolName);
  318.                 docConn    = CMNew(CMGetProcID(toolName), cmData, sizes, 0, 0);
  319.                 if (docConn != nil)
  320.                 {
  321.                     cmChooseReturnCode    = CMChoose(&docConn, where, nil);
  322.                 }
  323.             }
  324.             
  325.             if ((cmChooseReturnCode == chooseOKMinor) || (cmChooseReturnCode == chooseOKMajor))
  326.             {
  327.                 /* change the prefs file */
  328.                 
  329.                 if (prefFileOKFlag == 0xAA)
  330.                 {
  331.                     /* open the preference file */
  332.                     prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsFileName, fsRdWrPerm);
  333.                     if (prefRefNum != -1)
  334.                     {
  335.                         /* write the prefered tool name to the preference file */
  336.                         HLock((Handle) docConn);
  337.                         CMGetToolName((**docConn).procID, toolName);
  338.                         HUnlock((Handle) docConn);
  339.                         
  340.                         /* get the port TeXT resource */
  341.                         h = Get1Resource('pTXT', 0);
  342.                         if (h == nil)
  343.                         {
  344.                             /* resource did not exist, add it to resource file */
  345.                             h = NewHandle(1 + toolName[0]);
  346.                             HLock(h);
  347.                             BlockMove(toolName, *h, GetHandleSize(h));
  348.                             HUnlock(h);
  349.                             AddResource(h, 'pTXT', 0, "");
  350.                         }
  351.                         else
  352.                         {
  353.                             /* resoure DOES exist, change it */
  354.                             hSize = GetHandleSize(h);            /* get the size of the handle */
  355.                             /* check for size of handle */
  356.                             if (hSize != (1 + toolName[0]))
  357.                             {
  358.                                 newSize = 1 + toolName[0];
  359.                                 SetHandleSize(h, newSize);
  360.                             }
  361.                             HLock(h);
  362.                             BlockMove(toolName, *h, GetHandleSize(h));
  363.                             HUnlock(h);
  364.                             ChangedResource(h);
  365.                         }
  366.                         ReleaseResource(h);
  367.                         
  368.                         /* write the prefered configuration to the preference file */
  369.                         p = CMGetConfig(docConn);
  370.     
  371.     
  372.                         /* get the configuration TeXT resource */
  373.                         h = Get1Resource('cTXT', 0);
  374.                         if (h == nil)
  375.                         {
  376.                             /* resource did not exist, add it to resource file */
  377.                             h = NewHandle(GetPtrSize(p));
  378.                             HLock(h);
  379.                             BlockMove(p, *h, GetHandleSize(h));
  380.                             HUnlock(h);
  381.                         
  382.                             AddResource(h, 'cTXT', 0, "");
  383.                             iErr = ResError();
  384.                         }
  385.                         else
  386.                         {
  387.                             /* resoure DOES exist, change it */
  388.                             hSize = GetHandleSize(h);            /* get the size of the handle */
  389.                             /* check for size of handle */
  390.                             if (hSize != GetPtrSize(p))
  391.                             {
  392.                                 newSize = GetPtrSize(p);
  393.                                 SetHandleSize(h, newSize);
  394.                             }
  395.                             HLock(h);
  396.                             BlockMove(p, *h, GetHandleSize(h));
  397.                             HUnlock(h);
  398.                             ChangedResource(h);
  399.                         }
  400.                         ReleaseResource(h);
  401.     
  402.                         CloseResFile(prefRefNum);
  403.                         iErr = ResError();
  404.                         DisposPtr(p);
  405.                     }
  406.                 }
  407.             }
  408.             
  409.             if (docConn != nil)
  410.             {
  411.                 /* dispose of the connection */
  412.                 CMDispose(docConn);
  413.             }
  414.     
  415.         }
  416.     }
  417. }
  418.  
  419.  
  420. DoCommPortSetup(prefsFileName)
  421. Str255    prefsFileName;
  422. {
  423.     setCTBpref(prefsFileName);
  424.  
  425. }
  426.  
  427.  
  428. -------------------------------------
  429. Mark Sproul - KB2ICI
  430.  
  431.